package com.yxw.live_vod_boot.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yxw.live_vod_backend_facade.feign.ProductFeignClient;
import com.yxw.live_vod_backend_facade.vo.ProductVO;
import com.yxw.live_vod_boot.dto.*;
import com.yxw.live_vod_boot.entity.YxLiveActivityProductsEntity;
import com.yxw.live_vod_boot.entity.YxOrderEntity;
import com.yxw.live_vod_boot.entity.YxVodProductEntity;
import com.yxw.live_vod_boot.enums.MqttTopicEnum;
import com.yxw.live_vod_boot.exception.GlobalCustomerException;
import com.yxw.live_vod_boot.mapper.OrderMapper;
import com.yxw.live_vod_boot.mapper.ShopMapper;
import com.yxw.live_vod_boot.mapper.VodProductMapper;
import com.yxw.live_vod_boot.mapper.YxLiveActivityProductsMapper;
import com.yxw.live_vod_boot.mqtt.MqttGateway;
import com.yxw.live_vod_boot.service.*;
import com.yxw.live_vod_boot.utils.AssertUtil;
import com.yxw.live_vod_boot.utils.JsonUtils;
import com.yxw.live_vod_boot.utils.PageUtils;
import com.yxw.live_vod_boot.utils.RedisManager;
import com.yxw.live_vod_boot.vo.OrderVO;
import com.yxw.live_vod_boot.vo.ShopHomePageVO;
import com.yxw.live_vod_boot.vo.ShopOrderListVO;
import com.yxw.live_vod_boot.vo.UserInfoVo;
import com.yxw.live_vod_facade.constant.LiveShopConstant;
import com.yxw.live_vod_facade.enums.NoticeTypeEnum;
import com.yxw.live_vod_facade.vo.LiveActivityProductsVO;
import com.yxw.live_vod_facade.vo.LivePushStreamRedisCacheVO;
import com.yxw.yxnet_cd_center.common.constant.CommonConstant;
import com.yxw.yxnet_cd_center.common.constant.OrderCouponStatusCons;
import com.yxw.yxnet_cd_center.common.constant.OrderStatusCons;
import com.yxw.yxnet_cd_center.common.constant.RedisIdConstant;
import com.yxw.yxnet_cd_center.common.dto.PageVO;
import com.yxw.yxnet_cd_center.common.enums.ErrorCodeEnum;
import com.yxw.yxnet_cd_center.common.exception.BaseException;
import com.yxw.yxnet_cd_center.common.utils.BaseResult;
import com.yxw.yxnet_cd_center.common.utils.IdWorkerUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * @author Administrator
 */
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, YxOrderEntity> implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private ProductFeignClient productFeignClient;

    @Autowired
    private RedisManager redisManager;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private YxLiveActivityProductsMapper oYxLiveActivityProductsMapper;

    @Autowired
    private ShopMapper shopMapper;

    @Autowired

    private MqttGateway mqttGateway;

    @Autowired
    private VodProductMapper vodProductMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private LiveProcessService liveProcessService;

    @Autowired
    private BalanceDetailService balanceDetailService;

    @Autowired
    private SysNoticeService sysNoticeService;

    /**
     * 查询某一店铺下的订单列表
     * @param dto
     * @return
     */
    @Override
    public PageVO<ShopOrderListVO> getOrderListByShopId(ShopOrderListQueryDTO dto) {
        Page<ShopOrderListVO> page = new Page<>(dto.getCurrPage(), dto.getPageSize());
        // 需要校验当前查询的是不是自己的店铺
        Integer count = orderMapper.checkShopAdmin(dto.getUserId(), dto.getShopId());
        if (Integer.valueOf(0).equals(count) || null == count) {
            throw new GlobalCustomerException(ErrorCodeEnum.ILLEGAL_OPERATION);
        }
        List<ShopOrderListVO> volist = orderMapper.getOrderListByShopId(page, dto);
        return PageUtils.get(page, volist);
    }

    /**
     * 根据商品id查询订单列表
     * @param productId
     * @return
     */
    @Override
    public List<OrderVO> getOrderByProduct(Long productId) {
        LambdaQueryWrapper<YxOrderEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(productId != null, YxOrderEntity::getProductId, productId);
        List<YxOrderEntity> orderEntities = baseMapper.selectList(queryWrapper);
        List<OrderVO> list = new ArrayList<>();
        if (orderEntities != null && !orderEntities.isEmpty()) {
            list = BeanUtil.copyToList(orderEntities, OrderVO.class);
        }
        return list;
    }

    @Override
    public List<OrderVO> getOrderByLive(Long liveId) {
        LambdaQueryWrapper<YxOrderEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(liveId != null, YxOrderEntity::getBussId, liveId);
        List<YxOrderEntity> orderEntities = baseMapper.selectList(queryWrapper);
        List<OrderVO> list = new ArrayList<>();
        if (orderEntities != null && !orderEntities.isEmpty()) {
            list = BeanUtil.copyToList(orderEntities, OrderVO.class);
        }
        return list;
    }

    /**
     * 后台获取订单列表
     * @param queryDTO
     * @return
     */
    @Override
    public PageVO<OrderVO> getOrderList(OrderQueryDTO queryDTO) {
        Page<OrderVO> page = new Page<>(queryDTO.getCurrPage(), queryDTO.getPageSize());
        List<OrderVO> list = orderMapper.getOrderList(page, queryDTO);
        return PageUtils.get(page, list);
    }

    /**
     * 后台获取订单详情
     * @param orderId
     * @return
     */
    @Override
    public OrderVO getOrderById(Long orderId) {
        YxOrderEntity order = orderMapper.selectById(orderId);
        OrderVO vo = new OrderVO();
        BeanUtils.copyProperties(order, vo);
        return vo;
    }

    /**
     * 获取用户侧订单列表
     * @param queryDTO
     * @return
     */
    @Override
    public PageVO<OrderVO> getOrderListByUserId(UserOrderQueryDTO queryDTO) {
        Page<OrderVO> page = new Page<>(queryDTO.getCurrPage(), queryDTO.getPageSize());
        List<OrderVO> list = orderMapper.getOrderListByUserId(page, queryDTO);
        return PageUtils.get(page, list);
    }

    /**
     * 核销订单券码
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void verifyOrderCouponNum(VerifyOrderCouponNumDTO dto) {
        // 校验有没有这笔订单
        LambdaQueryWrapper<YxOrderEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(YxOrderEntity::getShopId, dto.getShopId());
        wrapper.eq(YxOrderEntity::getOrderCouponNum, dto.getOrderCouponNum());
        YxOrderEntity yxOrderEntity = orderMapper.selectOne(wrapper);
        AssertUtil.isNotNull(yxOrderEntity, ErrorCodeEnum.ORDER_COUPON_NUMBER_IS_FALSE);
        // 校验订单券码是否有效
        AssertUtil.isTrue(yxOrderEntity.getOrderCouponStatus() == OrderCouponStatusCons.COUPON_STATUS_PENDING, ErrorCodeEnum.COUPON_IS_VERIFIED_OR_USED);
        // 核验券码
        if (null != yxOrderEntity.getOrderCouponNum()) {
            if (dto.getOrderCouponNum().equals(yxOrderEntity.getOrderCouponNum())) {
                yxOrderEntity.setOrderCouponStatus(OrderCouponStatusCons.COUPON_STATUS_VERIFIED);
                yxOrderEntity.setCompletionTime(new Date());
                yxOrderEntity.setOrderStatus(OrderStatusCons.ORDER_STATUS_ACCOMPLISH);
                orderMapper.updateById(yxOrderEntity);
            } else {
                throw new GlobalCustomerException(ErrorCodeEnum.ORDER_COUPON_NUMBER_IS_FALSE);
            }
        }
        // 订单完成后新增店铺余额明细
        BalanceDetailAddDTO addDTO = new BalanceDetailAddDTO();
        addDTO.setOrderId(yxOrderEntity.getOrderId());
        addDTO.setDetail(CommonConstant.ZERO);
        addDTO.setType(CommonConstant.ONE);
        balanceDetailService.addBalanceDetail(addDTO);
        // 添加券码核验日志
        Long orderId = yxOrderEntity.getOrderId();
        orderMapper.insertVerifyOrderCouponNumLog(dto, orderId);
        try {
            // 发送订单系统消息
            SendInteractMsgDto msgDto=new SendInteractMsgDto();
            msgDto.setBussId(String.valueOf(yxOrderEntity.getOrderId()));
            msgDto.setUserId(yxOrderEntity.getUserId());
            msgDto.setUserName(yxOrderEntity.getUserName());
            msgDto.setType(NoticeTypeEnum.USE_SUCCESS);
            sysNoticeService.sendNotice(msgDto);
        } catch (Exception e) {
            log.error("订单消息发送失败：==================================================>" + e.getMessage());
        }
    }

    /**
     * 生成待支付订单
     * @param addDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addOrder(OrderAddDTO addDTO) {
        UserInfoVo userInfo = userService.getUserInfo(addDTO.getUserId());
        if (userInfo == null){
            throw new BaseException("用户不存在!");
        }
        ShopHomePageVO shop = null;
        YxLiveActivityProductsEntity activityProducts = null;
        if (addDTO.getActivityProductId() != null){
            activityProducts = oYxLiveActivityProductsMapper.selectById(addDTO.getActivityProductId());
        }
        if (activityProducts == null){
            throw new BaseException("下单失败，当前直播商品不存在");
        }
        // 创建订单实体对象
        YxOrderEntity order = new YxOrderEntity();
        if (addDTO.getOrderSource() == 0){
            String liveApplyKey = LiveShopConstant.LIVE_APPLY_REDISKEY_PREFIX.concat(addDTO.getApplyId());
            boolean exists = Boolean.TRUE.equals(redisTemplate.hasKey(liveApplyKey));
            if (!exists) {
                throw new BaseException("下单失败,当前直播不存在!");
            }
            BaseResult<ProductVO> product = productFeignClient.getProductById(Long.parseLong(activityProducts.getProductId()));
            if (activityProducts.getProductRemainderNumber().intValue() <= 0 || activityProducts.getProductRemainderNumber().intValue() > product.getData().getTotalCnt()){
                throw new BaseException("添加订单失败,商品库存不足!");
            }
            if (activityProducts.getShopId() != null){
                shop = shopMapper.getShopByShopId(Long.valueOf(activityProducts.getShopId()));
            }
            if (activityProducts.getLiveShopId() != null){
                shop = shopMapper.getShopHomePage(activityProducts.getLiveShopId());
            }
            order.setBussId(activityProducts.getLiveId());
            // 直播商品Id
            order.setProductId(activityProducts.getId());
            if (activityProducts.getProductDetailPicture() != null){
                String[] detailPic = activityProducts.getProductDetailPicture().split(",");
                order.setProductPic(detailPic[0]);
            }
            order.setProductName(activityProducts.getProductName());
            order.setCategoryId(activityProducts.getCategoryId());
            order.setProductCategory(activityProducts.getCategoryName());
            order.setProductSpecification(activityProducts.getSpecificationValues());
            order.setProductStyle(product.getData().getStyle());
            if (shop != null){
                order.setShopId(shop.getLiveShopId());
                order.setShopName(shop.getShopName());
            }
            order.setProductAmount(activityProducts.getProductPrice());
            order.setActualAmount(activityProducts.getProductLivePrice());
        }
        if (addDTO.getOrderSource() == 1){
            //查询点播商品信息
            LambdaQueryWrapper<YxVodProductEntity> proWrapper = new LambdaQueryWrapper<>();
            proWrapper.eq(YxVodProductEntity::getVideoId,addDTO.getVideoId());
            proWrapper.eq(YxVodProductEntity::getStatus,CommonConstant.ONE);
            YxVodProductEntity proEntity = vodProductMapper.selectOne(proWrapper);
            if (proEntity != null){
                BaseResult<ProductVO> product = productFeignClient.getProductById(proEntity.getProductId());
                if (product == null || product.getData() == null) {
                    log.error("添加订单失败：获取商品信息失败");
                    throw new BaseException("获取商品信息失败");
                }
                ProductVO productVO = product.getData();
                if (productVO.getTotalCnt() <= 0) {
                    throw new BaseException("添加订单失败,商品库存不足!");
                }
                order.setShopId(productVO.getShopId());
                order.setShopName(productVO.getShopName());
                order.setCategoryId(productVO.getCategoryId());
                order.setProductCategory(productVO.getProductCategory());
                order.setProductSpecification(productVO.getProductSpecification());
                order.setProductId(productVO.getProductId());
                order.setProductName(productVO.getProductName());
                if (productVO.getProductMasterPic() != null && productVO.getProductMasterPic().length > 0) {
                    order.setProductPic(productVO.getProductMasterPic()[CommonConstant.ZERO]);
                }
                order.setProductAmount(productVO.getProductPrice());
                order.setActualAmount(productVO.getCutPrice());
            }
        }
        if (addDTO.getOrderSource() == 2){
            BaseResult<ProductVO> product = productFeignClient.getProductById(addDTO.getProductId());
            if (product == null || product.getData() == null) {
                log.error("添加订单失败：获取商品信息失败");
                throw new BaseException("获取商品信息失败");
            }
            ProductVO productVO = product.getData();
            if (productVO.getTotalCnt() <= 0) {
                throw new BaseException("添加订单失败,商品库存不足!");
            }
            order.setShopId(productVO.getShopId());
            order.setShopName(productVO.getShopName());
            order.setCategoryId(productVO.getCategoryId());
            order.setProductCategory(productVO.getProductCategory());
            order.setProductSpecification(productVO.getProductSpecification());
            order.setProductId(productVO.getProductId());
            order.setProductName(productVO.getProductName());
            if (productVO.getProductMasterPic() != null && productVO.getProductMasterPic().length > 0) {
                order.setProductPic(productVO.getProductMasterPic()[CommonConstant.ZERO]);
            }
            order.setProductAmount(productVO.getProductPrice());
            order.setActualAmount(productVO.getCutPrice());
        }
        order.setUserId(addDTO.getUserId());
        order.setProductQuantity(addDTO.getProductQuantity());
        order.setOrderSource(addDTO.getOrderSource());
        order.setUserName(userInfo.getUserName());
        order.setUserPhone(userInfo.getPhone());
        order.setOrderNum(IdWorkerUtils.generateTransactionNumberRandom());
        order.setOrderStatus(OrderStatusCons.ORDER_STATUS_UNPAID);
        order.setOrderTime(new Date());
        // 插入订单数据到数据库
        int insertCount = baseMapper.insert(order);
        if (insertCount <= 0) {
            throw new BaseException("添加订单失败,服务器忙，请稍后再试！");
        }
        String redisKey = LiveShopConstant.LIVE_SHOP_USER_ORDER_SHOP_HASHMAP_PREFIX.concat(order.getUserId().toString());
        redisManager.setMapValue(redisKey, order.getShopId().toString(), order.getShopId().toString());
        if (addDTO.getOrderSource() == 0){
            LiveProductStockDTO liveProductStockDTO = new LiveProductStockDTO();
            liveProductStockDTO.setLiveId(activityProducts.getLiveId());
            liveProductStockDTO.setProductQuantity(addDTO.getProductQuantity());
            liveProductStockDTO.setActivityProductId(addDTO.getActivityProductId());
            liveProductStock(liveProductStockDTO);
        }else {
            ProductStockDTO stockDTO = new ProductStockDTO();
            stockDTO.setProductId(addDTO.getProductId());
            stockDTO.setProductQuantity(addDTO.getProductQuantity());
            purchaseItem(stockDTO);
        }
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(order,orderVO);
        // 将订单信息发送到 MQTT 主题
        mqttGateway.sendToMqtt(MqttTopicEnum.ORDER_TIMEOUT_TOPIC.getTopic()+order.getOrderId(), JsonUtils.toJson(orderVO), 30 * 60 * 1000L);
        try {
            // 发送订单系统消息
            SendInteractMsgDto msgDto=new SendInteractMsgDto();
            msgDto.setBussId(String.valueOf(order.getOrderId()));
            msgDto.setUserId(order.getUserId());
            msgDto.setUserName(order.getUserName());
            msgDto.setType(NoticeTypeEnum.ORDER_SUCCESS);
            sysNoticeService.sendNotice(msgDto);
        } catch (Exception e) {
            log.error("订单消息发送失败：==================================================>" + e.getMessage());
        }
    }

    /**
     * 订单30分钟过期倒计时
     * @param order
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void checkOrderExpiration(OrderVO order) {
        LocalDateTime createTime = order.getOrderTime().toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
        LocalDateTime expireTime = createTime.plusMinutes(30);
        LocalDateTime now = LocalDateTime.now();
        Duration duration = Duration.between(now, expireTime);
        long minutesRemaining = duration.toMinutes();
        if (minutesRemaining <= 0) {
            // 设置订单状态为过期
            order.setOrderStatus(OrderStatusCons.ORDER_STATUS_CANCEL_ORDER);
            YxOrderEntity orderEntity = new YxOrderEntity();
            BeanUtils.copyProperties(order, orderEntity);
            // 更新订单状态到数据库
            orderMapper.updateById(orderEntity);
            log.info("订单已过期,订单编号:{}, 订单id:{}", order.getOrderNum(), order.getOrderId());
            // 处理订单过期后的逻辑
            handleOrderExpiration(order);
        }
    }

    /**
     * 处理订单过期后的逻辑
     * @param order
     */
    private void handleOrderExpiration(OrderVO order) {
        if (order.getOrderSource() == 0) {
            LiveProductStockDTO liveProductStockDTO = new LiveProductStockDTO();
            liveProductStockDTO.setLiveId(order.getBussId());
            liveProductStockDTO.setProductQuantity(order.getProductQuantity());
            liveProductStockDTO.setActivityProductId(order.getProductId());
            adjustProductStock(liveProductStockDTO);
        } else {
            ProductStockDTO stockDTO = new ProductStockDTO();
            stockDTO.setProductId(order.getProductId());
            stockDTO.setProductQuantity(order.getProductQuantity());
            cancellationOrder(stockDTO);
        }
        try {
            // 发送订单系统消息
            SendInteractMsgDto msgDto=new SendInteractMsgDto();
            msgDto.setBussId(String.valueOf(order.getOrderId()));
            msgDto.setUserId(order.getUserId());
            msgDto.setUserName(order.getUserName());
            msgDto.setType(NoticeTypeEnum.ORDER_NOT_PAY);
            sysNoticeService.sendNotice(msgDto);
        } catch (Exception e) {
            log.error("订单消息发送失败：==================================================>" + e.getMessage());
        }
    }

    /**
     * 订单处理完成-删除订单
     * @param orderId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteOrder(Long orderId) {
        YxOrderEntity orderEntity = orderMapper.selectById(orderId);
        if (orderEntity == null) {
            throw new BaseException("订单不存在!");
        }
        orderEntity.setIsFlag(CommonConstant.ONE);
        baseMapper.updateById(orderEntity);
    }

    /**
     * 订单支付完成-申请退款
     * @param refundDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderRefund(OrderRefundDTO refundDTO) {
        YxOrderEntity orderEntity = orderMapper.selectById(refundDTO.getOrderId());
        if (orderEntity == null) {
            throw new BaseException("该订单不存在,申请退款失败!");
        }
        orderEntity.setRefundAmount(orderEntity.getActualAmount());
        orderEntity.setRefundReason(refundDTO.getRefundReason());
        orderEntity.setRefundQuantity(orderEntity.getProductQuantity());
        orderEntity.setRefundType(refundDTO.getRefundType());
        orderEntity.setRefundTime(new Date());
        orderEntity.setOrderStatus(OrderStatusCons.ORDER_STATUS_REFUND_SUCCESS);
        orderEntity.setOrderCouponStatus(OrderCouponStatusCons.COUPON_STATUS_INVALID);
        int updateCount = baseMapper.updateById(orderEntity);
        if (updateCount <= 0) {
            throw new BaseException("申请退款失败,服务器忙,请稍后再试!");
        }
        if (orderEntity.getOrderSource() == 0){
            LiveProductStockDTO liveProductStockDTO = new LiveProductStockDTO();
            liveProductStockDTO.setLiveId(orderEntity.getBussId());
            liveProductStockDTO.setProductQuantity(orderEntity.getProductQuantity());
            liveProductStockDTO.setActivityProductId(orderEntity.getProductId());
            adjustProductStock(liveProductStockDTO);
            liveProductRefund(liveProductStockDTO);
        }else {
            ProductStockDTO stockDTO = new ProductStockDTO();
            stockDTO.setProductId(orderEntity.getProductId());
            stockDTO.setProductQuantity(orderEntity.getProductQuantity());
            productRefund(stockDTO);
        }
        try {
            // 发送订单系统消息
            SendInteractMsgDto msgDto=new SendInteractMsgDto();
            msgDto.setBussId(String.valueOf(orderEntity.getOrderId()));
            msgDto.setUserId(orderEntity.getUserId());
            msgDto.setUserName(orderEntity.getUserName());
            msgDto.setType(NoticeTypeEnum.REFUND_SUCCESS);
            sysNoticeService.sendNotice(msgDto);
        } catch (Exception e) {
            log.error("订单消息发送失败：==================================================>" + e.getMessage());
        }
    }

    /**
     * 订单未支付-取消订单
     * @param orderId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelOrder(Long orderId) {
        // 查询订单信息
        YxOrderEntity orderEntity = orderMapper.selectById(orderId);
        if (orderEntity == null) {
            throw new BaseException("该订单不存在，取消订单失败");
        }
        // 判断订单状态是否允许取消
        if (orderEntity.getOrderStatus() != OrderStatusCons.ORDER_STATUS_UNPAID) {
            throw new BaseException("当前订单状态不允许取消");
        }
        // 更新订单状态为已取消
        orderEntity.setOrderCouponStatus(OrderCouponStatusCons.COUPON_STATUS_INVALID);
        orderEntity.setOrderStatus(OrderStatusCons.ORDER_STATUS_CANCEL_ORDER);
        int updateCount = baseMapper.updateById(orderEntity);
        if (updateCount <= 0) {
            throw new BaseException("取消订单失败");
        }
        if (orderEntity.getOrderSource() == 0){
            LiveProductStockDTO liveProductStockDTO = new LiveProductStockDTO();
            liveProductStockDTO.setLiveId(orderEntity.getBussId());
            liveProductStockDTO.setProductQuantity(orderEntity.getProductQuantity());
            liveProductStockDTO.setActivityProductId(orderEntity.getProductId());
            adjustProductStock(liveProductStockDTO);
        }else {
            ProductStockDTO stockDTO = new ProductStockDTO();
            stockDTO.setProductId(orderEntity.getProductId());
            stockDTO.setProductQuantity(orderEntity.getProductQuantity());
            cancellationOrder(stockDTO);
        }
        try {
            // 发送订单系统消息
            SendInteractMsgDto msgDto=new SendInteractMsgDto();
            msgDto.setBussId(String.valueOf(orderEntity.getOrderId()));
            msgDto.setUserId(orderEntity.getUserId());
            msgDto.setUserName(orderEntity.getUserName());
            msgDto.setType(NoticeTypeEnum.ORDER_CANCEL);
            sysNoticeService.sendNotice(msgDto);
        } catch (Exception e) {
            log.error("订单消息发送失败：==================================================>" + e.getMessage());
        }
    }

    /**
     * 订单支付完成-待使用
     * @param orderId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderUse(Long orderId) {
        YxOrderEntity orderEntity = orderMapper.selectById(orderId);
        if (orderEntity == null) {
            throw new BaseException("该订单不存在!");
        }
        orderEntity.setOrderStatus(OrderStatusCons.ORDER_STATUS_PENDING);
        orderEntity.setOrderCouponNum(randomNumberGenerator());
        orderEntity.setPaymentWay("微信");
        orderEntity.setOrderCouponStatus(OrderCouponStatusCons.COUPON_STATUS_PENDING);
        baseMapper.updateById(orderEntity);
        // 核销完成从redis中取出库存相关并更新到数据库中
        YxLiveActivityProductsEntity activityProducts = oYxLiveActivityProductsMapper.selectById(orderEntity.getProductId());
        productFeignClient.getProductStock(Long.parseLong(activityProducts.getProductId()));
        if (orderEntity.getOrderSource() == 0){
            LiveProductStockDTO liveProductStockDTO = new LiveProductStockDTO();
            liveProductStockDTO.setLiveId(orderEntity.getBussId());
            liveProductStockDTO.setActivityProductId(orderEntity.getProductId());
            liveProductStockDTO.setProductQuantity(orderEntity.getProductQuantity());
            liveCompletionPayment(liveProductStockDTO);
        }else {
            ProductStockDTO stockDTO = new ProductStockDTO();
            stockDTO.setProductId(orderEntity.getProductId());
            stockDTO.setProductQuantity(orderEntity.getProductQuantity());
            completionPayment(stockDTO);
        }
    }


    /**
     * 暂定订单劵码生成为8位随机数字
     * @return
     */
    private Integer randomNumberGenerator() {
        Random random = new Random();
        int min = 10000000;
        int max = 99999999;
        return random.nextInt(max - min + 1) + min;
    }


    // -----------------库存的几种情况-------------------------------------------------------------------------------

    /**
     * 商品下单
     * @param dto
     */
    private void purchaseItem(ProductStockDTO dto) {
        // 总库存
        int totalCnt = getIntegerFromRedis(RedisIdConstant.PRODUCT_TOTAL_CNT + ":" + dto.getProductId());
        // 预占库存
        int preeCnt = getIntegerFromRedis(RedisIdConstant.PRODUCT_PREE_CNT + ":" + dto.getProductId());
        // 库存检查
        if (dto.getProductQuantity() > totalCnt) {
            throw new BaseException("商品下单失败,库存不足!");
        }
        if (0 >= totalCnt){
            productFeignClient.isPutAwayById(String.valueOf(dto.getProductId()),CommonConstant.ONE);
        }
        // 扣减总库存
        redisManager.decrBy(RedisIdConstant.PRODUCT_TOTAL_CNT + ":" + dto.getProductId(), dto.getProductQuantity());
        // 增加预占库存
        redisManager.incrBy(RedisIdConstant.PRODUCT_PREE_CNT + ":" + dto.getProductId(), dto.getProductQuantity());
    }

    /**
     * 支付完成
     * @param dto
     */
    private void completionPayment(ProductStockDTO dto) {
        // 预占库存
        int preeCnt = getIntegerFromRedis(RedisIdConstant.PRODUCT_PREE_CNT + ":" + dto.getProductId());
        // 库存检查
        if (dto.getProductQuantity() > preeCnt) {
            throw new BaseException("预占库存转移到实占库存失败,预占库存不足!");
        }
        // 扣减预占库存
        redisManager.decrBy(RedisIdConstant.PRODUCT_PREE_CNT + ":" + dto.getProductId(), dto.getProductQuantity());
        // 增加实占库存
        redisManager.incrBy(RedisIdConstant.PRODUCT_USE_CNT + ":" + dto.getProductId(), dto.getProductQuantity());
    }

    /**
     * 取消订单/未支付订单超时
     * @param dto
     */
    private void cancellationOrder(ProductStockDTO dto) {
        // 预占库存
        int preeCnt = getIntegerFromRedis(RedisIdConstant.PRODUCT_PREE_CNT + ":" + dto.getProductId());
        // 库存检查
        if (dto.getProductQuantity() > preeCnt) {
            throw new BaseException("预占库存转移到总库存失败,预占库存不足!");
        }
        // 扣减预占库存
        redisManager.decrBy(RedisIdConstant.PRODUCT_PREE_CNT + ":" + dto.getProductId(), dto.getProductQuantity());
        // 增加总库存
        redisManager.incrBy(RedisIdConstant.PRODUCT_TOTAL_CNT + ":" + dto.getProductId(), dto.getProductQuantity());
    }

    /**
     * 支付完成后退款
     * @param dto
     */
    private void productRefund(ProductStockDTO dto) {
        // 实占库存
        int useCnt = getIntegerFromRedis(RedisIdConstant.PRODUCT_USE_CNT + ":" + dto.getProductId());
        if (dto.getProductQuantity() > useCnt) {
            throw new BaseException("实占库存转移到总库存失败,实占库存不足!");
        }
        // 扣减实占库存
        redisManager.decrBy(RedisIdConstant.PRODUCT_USE_CNT + ":" + dto.getProductId(), dto.getProductQuantity());
        // 增加总库存
        redisManager.incrBy(RedisIdConstant.PRODUCT_TOTAL_CNT + ":" + dto.getProductId(), dto.getProductQuantity());
    }

    /**
     * 查询Redis中的值并将其转换为整数
     * @param key
     * @return
     */
    private int getIntegerFromRedis(String key) {
        Object obj = redisManager.get(key);
        if (obj == null) {
            return 0;
        }
        try {
            return Integer.parseInt(obj.toString());
        } catch (NumberFormatException e) {
            log.error("无法将{}转换为整数", obj, e);
            throw new BaseException("转换失败");
        }
    }

    // ---------------直播库存--------------------------------------------

    /**
     * 直播商品下单 -- 库存分开计算
     * @param dto
     */
    private void liveProductStock(LiveProductStockDTO dto){
        String redisKey = LiveShopConstant.LIVE_PUSH_STREAM_CACHE_REDISKEY_PREFIX.concat(dto.getLiveId());
        Object o = redisManager.get(redisKey);
        String productRedisKey = null;
        LiveActivityProductsVO liveActivityProductsVO = null;
        if (o != null){
            Object mapValue = redisManager.getMapValue(LiveShopConstant.LIVE_SHOP_PRODUCT_REDISKEY_PREFIX.concat(dto.getLiveId()), dto.getActivityProductId().toString());
            if (mapValue != null){
                ObjectMapper objectMapper = new ObjectMapper();
                liveActivityProductsVO = objectMapper.convertValue(mapValue, LiveActivityProductsVO.class);
            }
            if(null != liveActivityProductsVO) {
                BigDecimal productRemainderNumber = liveActivityProductsVO.getProductRemainderNumber();
                long productNumber = productRemainderNumber.longValue();
                productRedisKey = RedisIdConstant.PRODUCT_LIVE_CNT + ":" + dto.getActivityProductId();
                // 当redis中没有key时,将需要处理的库存字段保存到redis中
                boolean exists = Boolean.TRUE.equals(redisTemplate.hasKey(productRedisKey));
                if (!exists) {
                    redisManager.set(productRedisKey, productNumber);
                }
                // 获取redis中的总库存
                String totalCnt = RedisIdConstant.PRODUCT_TOTAL_CNT + ":" + liveActivityProductsVO.getProductId();
                Object o1 = redisManager.get(totalCnt);
                if (o1 != null){
                    int i = (Integer)o1;
                    if(i < productNumber){
                        throw new BaseException("库存不足,下单失败!");
                    }
                    if (0 >= i){
                        productFeignClient.isPutAwayById(liveActivityProductsVO.getProductId(),CommonConstant.ONE);
                    }
                    // 有就直接进行扣减处理
                    redisManager.decrBy(productRedisKey, dto.getProductQuantity());
                    // 扣减总库存
                    redisManager.decrBy(totalCnt, dto.getProductQuantity());
                }
            }
        }
    }

    /**
     * 直播商品支付完成
     * @param dto
     */
    private void liveCompletionPayment(LiveProductStockDTO dto) {
        YxLiveActivityProductsEntity activityProducts = oYxLiveActivityProductsMapper.selectById(dto.getActivityProductId());
        if (activityProducts == null) {
            throw new BaseException("商品不存在!");
        } 
        String orderTotalCountKey = LiveShopConstant.LIVE_SHOP_ORDER_TOTAL_COUNT_REDISKEY_PREFIX.concat(dto.getLiveId());
        String orderTotalFeeKey = LiveShopConstant.LIVE_SHOP_ORDER_TOTAL_FEE_REDISKEY_PREFIX.concat(dto.getLiveId());
        String redisLiveStateCheckKey = LiveShopConstant.LIVE_SHOP_ONLINELIVE_STATE_CHECK_PREFIX.concat(dto.getLiveId());
        Object o = redisManager.get(redisLiveStateCheckKey);
        if (o != null){
            Integer liveState = (Integer)o;
            if (liveState == 1){
                // 直播订单数量增加
                redisManager.incrBy(orderTotalCountKey, CommonConstant.ONE);
                // 直播订单金额增加
                redisManager.incrBy(orderTotalFeeKey, activityProducts.getProductLivePrice().longValue());
                // 增加实占库存
                redisManager.incrBy(RedisIdConstant.PRODUCT_USE_CNT + ":" + activityProducts.getProductId(), dto.getProductQuantity());
            }
        }
    }

    /**
     * 直播商品支付完成后退款
     * @param dto
     */
    private void liveProductRefund(LiveProductStockDTO dto) {
        YxLiveActivityProductsEntity activityProducts = oYxLiveActivityProductsMapper.selectById(dto.getActivityProductId());
        if (activityProducts == null) {
            throw new BaseException("商品不存在!");
        }
        String orderTotalCountKey = LiveShopConstant.LIVE_SHOP_ORDER_TOTAL_COUNT_REDISKEY_PREFIX.concat(dto.getLiveId());
        String orderTotalFeeKey = LiveShopConstant.LIVE_SHOP_ORDER_TOTAL_FEE_REDISKEY_PREFIX.concat(dto.getLiveId());
        String liveAddressKey = LiveShopConstant.LIVE_PUSH_STREAM_CACHE_REDISKEY_PREFIX.concat(dto.getLiveId());
        String redisLiveStateCheckKey = LiveShopConstant.LIVE_SHOP_ONLINELIVE_STATE_CHECK_PREFIX.concat(dto.getLiveId());
        Object oTmp = redisManager.get(redisLiveStateCheckKey);
        if (oTmp != null){
            Integer liveState = (Integer)oTmp;
            Object o = redisManager.get(liveAddressKey);
            if (o != null){
                LivePushStreamRedisCacheVO oLiveRedisCacheVO = (LivePushStreamRedisCacheVO)o;
                if (liveState < 4){
                    // 直播订单数量减少
                    redisManager.decrBy(orderTotalCountKey, CommonConstant.ONE);
                    // 直播订单金额减少
                    redisManager.decrBy(orderTotalFeeKey, activityProducts.getProductLivePrice().longValue());
                }else if (liveState >= 4){
                    liveProcessService.liveOrderDecr(oLiveRedisCacheVO.getApplyId(), dto.getLiveId(), activityProducts.getProductLivePrice());
                }else if (oLiveRedisCacheVO.getLiveEndTime() < System.currentTimeMillis()){//Long.parseLong(new Date().toString())
                    liveProcessService.liveOrderDecr(oLiveRedisCacheVO.getApplyId(), dto.getLiveId(), activityProducts.getProductLivePrice());
                }
            }
        }
    }

    /**
     * 取消订单/订单超时/支付完成后退款通用
     * @param dto
     */
    private void adjustProductStock(LiveProductStockDTO dto) {
        String redisKey = LiveShopConstant.LIVE_PUSH_STREAM_CACHE_REDISKEY_PREFIX.concat(dto.getLiveId());
        String productRedisKey = RedisIdConstant.PRODUCT_LIVE_CNT + ":" + dto.getActivityProductId();
        Object o = redisManager.get(redisKey);
        if (o != null) {
            // 获取直播数据
            YxLiveActivityProductsEntity oYxLiveActivityProductsEntity =  redisManager.getMapValue(LiveShopConstant.LIVE_SHOP_PRODUCT_REDISKEY_PREFIX.concat(dto.getLiveId()), dto.getActivityProductId().toString());
            if(null != oYxLiveActivityProductsEntity) {
                String totalCntKey = RedisIdConstant.PRODUCT_TOTAL_CNT + ":" + oYxLiveActivityProductsEntity.getProductId();
                // 直播商品库存与总库存同时增加回去
                redisManager.incrBy(productRedisKey, dto.getProductQuantity());
                redisManager.incrBy(totalCntKey, dto.getProductQuantity());
                // 扣减实占库存
                redisManager.decrBy(RedisIdConstant.PRODUCT_USE_CNT + ":" + oYxLiveActivityProductsEntity.getProductId(), dto.getProductQuantity());
            }
        }
    }
}
